﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using T19_ShotBlock.BaseClass;
using System.Runtime.InteropServices;

namespace T19_ShotBlock
{
    public partial class Form1 : Form
    {
        private Bitmap bmBackground;//背景图片
        private Bitmap bmpaddle;//挡板图片资源
        private static readonly Rectangle GamePaddleRect
            = new Rectangle(39, 1, 93, 23);//挡板资源在合图中的矩形位置
        private Point centerOfPaddle;//挡板中心位置

        private Bitmap bmBlock;
        private static readonly Rectangle GameBlockRect
            = new Rectangle(139, 1, 62, 27);//砖块资源在合图中的矩形位置
        private Block[,] blocks = new Block[12, 14];//砖块显示地图

        private int gameLevel = 1;//游戏级数

        private Bitmap bmBall;
        private Rectangle paddleRect;//挡板位置
        private static readonly Rectangle GameBallRect = new Rectangle(1, 1, 36, 36);//弹球资源

       

        [DllImport("winmm")]
        public static extern bool PlaySound(string szSound, int hMode, int i);//音效播放扩展

        private int gameLives = 4;//玩家生命值：5

        private bool isGameOver = false;//游戏结束状态

        private bool bSounding = false;//音效播放控制

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.LoadPictures();
            //设置挡板的初始位置
            centerOfPaddle.X = this.ClientRectangle.Width / 2;//屏幕中间（水平）
            centerOfPaddle.Y = this.ClientRectangle.Height - 30;//屏幕底部略上（垂直）

            this.RandomBlockMap();

            Ball.BallRect = new Rectangle(centerOfPaddle.X - 36 / 2, centerOfPaddle.Y - 32, 36, 36);
            Ball.BallDirection = new Vector2(1.0f, -1.0f);

            paddleRect = new Rectangle(this.ClientRectangle.Width / 2 - 48,
                this.ClientRectangle.Height - 33,
                96, 26);

            this.TimerRerfreshScreen.Start();
        }

        //利用双缓冲机制绘制游戏界面
        protected override void OnPaint(PaintEventArgs e)
        {
            //在内存中建立绘制区域
            Bitmap bufferBm = new Bitmap(this.ClientRectangle.Width - 1,
                this.ClientRectangle.Height - 1);
            Graphics g = Graphics.FromImage(bufferBm);
            //在内存中绘制所有图片资源
            this.DrawGame(g);
            //把内存中的区域一次性绘制在屏幕上
            e.Graphics.DrawImage(bufferBm, 0, 0);
            //释放当前内存区域
            g.Dispose();
            base.OnPaint(e);
        }
        /// <summary>
        /// 载入图片资源
        /// </summary>
        private void LoadPictures()
        {
            bmBackground = BitmapHelper.LoadBm("Background");
            Bitmap bmBreak = BitmapHelper.LoadBm("Break");
            //从"Break.bmp"合图中的指定位置复制挡板资源图片
            bmpaddle = bmBreak.Clone(GamePaddleRect, bmBreak.PixelFormat);
            //从"Break.bmp"合图中的指定位置复制图片资源图片
            bmBlock = bmBreak.Clone(GameBlockRect, bmBreak.PixelFormat);
            //从"Break.bmp"合图中的指定位置复制弹球图片资源图片
            bmBall = bmBreak.Clone(GameBallRect, bmBreak.PixelFormat);
        }
        /// <summary>
        /// 游戏界面绘制
        /// </summary>
        /// <param name="g"></param>
        private void DrawGame(Graphics g)
        {
            //绘制背景
            g.DrawImage(bmBackground,
                new Rectangle(0, 0,
                this.ClientRectangle.Width - 1,
                this.ClientRectangle.Height - 1)
                );
            //绘制挡板 宽93 高23
            g.DrawImage(bmpaddle,
                new Rectangle(centerOfPaddle.X - 93 / 2, centerOfPaddle.Y, 93, 23));
            //绘制砖块 宽度62 高度27
            for (int row = 0; row < 12; row++)
            {
                for (int col = 0; col < 14; col++)
                {
                    if (blocks[row, col].IsBlock)
                    {
                        g.DrawImage(bmBlock, blocks[row, col].BlickRect);
                    }
                }
            }
            //绘制弹球 高度：36 宽度：36
            //绘制静态弹球
            //g.DrawImage(bmBall, new Rectangle(centerOfPaddle.X -36/2, centerOfPaddle.Y - 36, 36, 36));
            //绘制动态弹球
            g.DrawImage(bmBall, Ball.BallRect);

            //绘制游戏信息（文本方式）
            g.DrawString("关卡" + gameLevel.ToString(),
                new Font("仿宋", 24),
                new SolidBrush(Color.White),
                new Point(5, 5));
            g.DrawString("生命" + gameLives.ToString(),
               new Font("仿宋", 24),
               new SolidBrush(Color.White),
               new Point(500, 5));
            if (isGameOver)
            {
                g.DrawString("游戏结束！",
                    new Font("仿宋", 48),
               new SolidBrush(Color.White),
               new Point(240, 288));
            }

        }
        /// <summary>
        /// 处理鼠标移动事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmBlock_MouseMove(object sender, MouseEventArgs e)
        {
            //移动（水平移动）:改变Paddle的中心坐标，边界碰撞（游戏元素与游戏场景）处理
            if (e.X <= 93 / 2)//最左端
            {
                centerOfPaddle.X = 93 / 2;
            }
            else if (e.X >= this.ClientRectangle.Width - 93 / 2)//最右端
            {
                centerOfPaddle.X = this.ClientRectangle.Width - 93 / 2;
            }
            else
            {
                centerOfPaddle.X = e.X;
            }

            //更新挡板位置
            paddleRect.X = centerOfPaddle.X - 48;
            //this.Invalidate();
        }
        /// <summary>
        /// 产生随机砖块地图
        /// </summary>
        private void RandomBlockMap()
        {
            for (int row = 0; row < 12; row++)
            {
                for (int col = 0; col < 14; col++)
                {
                    blocks[row, col] = new Block();
                    if (RandomHelper.GetRandomInt() < gameLevel)
                    {
                        blocks[row, col].IsBlock = true;
                        blocks[row, col].BlickRect = new Rectangle(62 * col, row * 27 + 60, 62, 27);
                    }
                }
            }
        }
        /// <summary>
        /// 处理计时器工作：刷新屏幕显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TimerRerfreshScreen_Tick(object sender, EventArgs e)
        {
            Ball.BallRect.X += (int)(Ball.BallDirection.X * 8.0f);
            Ball.BallRect.Y += (int)(Ball.BallDirection.Y * 6.0f);
            //if (IsHit())
            //Play("Hit");
            //  if (IsKill())
            //Play("Kill");
            
            if (IsHit() && !bSounding)
            {
                Play("Hit");
                bSounding = true;
                this.TimeAfterSound.Start();
            }

            if (IsKill() && !bSounding)
            {
                Play("Kill");
                bSounding = true;
                this.TimeAfterSound.Start();
            }
            if (IsLost())
            {
                Play("Lost");
            }
            if (IsVictory())
            {
                Play("Victory");
                this.TimerRerfreshScreen.Stop();
                this.TimerWait.Start();
            }
            this.IsGameOver();
            if (isGameOver)
            {
                this.TimerRerfreshScreen.Stop();
            }

            this.Invalidate();
        }
        /// <summary>
        /// 关卡等待时间控制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TimerWait_Tick(object sender, EventArgs e)
        {
            this.TimerWait.Stop();
            gameLevel++;//进入下一关
            RandomBlockMap();//产生下一个的随机地图
            Ball.BallRect.X = this.ClientRectangle.Width / 2 - 18;
            Ball.BallRect.Y = this.ClientRectangle.Height - RandomHelper.GetRandomInt(35,60);
            Ball.BallDirection = new Vector2(1.0f, -1.0f);
            this.TimerRerfreshScreen.Start();

        }

        /// <summary>
        /// 音效间隔播放控制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TimeAfterSound_Tick(object sender, EventArgs e)
        {
            bSounding = false;
            this.TimeAfterSound.Stop();
        }
        /// <summary>
        /// 碰撞边界处理:改变弹球的方向
        /// </summary>
        /// <returns></returns>
        private bool IsHit()
        {
            //与边框碰撞
            if (Ball.BallRect.X <= 3)//左
            {
                Ball.BallDirection.X = -Ball.BallDirection.X;
                return true;
            }
            if (Ball.BallRect.X >= this.ClientRectangle.Width - 39)//右边框
            {
                Ball.BallDirection.X = -Ball.BallDirection.X;
                return true;
            }
            if (Ball.BallRect.Y <= 3)//上边框
            {
                Ball.BallDirection.Y = -Ball.BallDirection.Y;
                return true;
            }
            if (Ball.BallRect.IntersectsWith(paddleRect))//挡板
            {
                Ball.BallDirection.Y = -Ball.BallDirection.Y;
                return true;
            }
            return false;
        }
        /// <summary>
        /// 与砖块发生碰撞
        /// </summary>
        /// <returns></returns>
        private bool IsKill()
        {
            for (int row = 0; row < 12; row++)
            {
                for (int col = 0; col < 14; col++)
                {
                    if (blocks[row, col].IsBlock && blocks[row, col].BlickRect.IntersectsWith(Ball.BallRect))
                    {
                        if (Math.Abs(blocks[row, col].BlickRect.X - Ball.BallRect.X) < 6 ||
                            Math.Abs(blocks[row, col].BlickRect.X - Ball.BallRect.X + 93 - 36) < 6)//与砖块的左右侧面发生碰撞
                        {
                            Ball.BallDirection.X = -Ball.BallDirection.X;
                        }
                        else//与砖块的上下面碰撞
                        {
                            Ball.BallDirection.Y = -Ball.BallDirection.Y;
                        }
                        //使砖块消失
                        blocks[row, col].IsBlock = false;
                        return true;
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 播放指定音效
        /// </summary>
        /// <param name="waveName"></param>
        private void Play(string waveName)
        {
            PlaySound(Application.StartupPath + "\\GameSounds\\" + waveName + ".wav", 0, 1);
        }
        /// <summary>
        /// 判断是否能接住球
        /// </summary>
        /// <returns></returns>
        private bool IsLost()
        {
            if (Ball.BallRect.Y > this.ClientRectangle.Height - 18)
            {
                Ball.BallRect.Y = this.ClientRectangle.Height - RandomHelper.GetRandomInt(35,60);
                Ball.BallDirection = new Vector2(1.0f, -1.0f);
                gameLives--;
                return true;
            }
            return false;
        }
        /// <summary>
        /// 判断当前关卡是否打完
        /// </summary>
        /// <returns></returns>
        private bool IsVictory()
        {
            for (int row = 0; row < 12; row++)
            {
                for (int col = 0; col < 14; col++)
                {
                    if (blocks[row, col].IsBlock)
                        return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 判断游戏是否结束
        /// </summary>
        private void IsGameOver()
        {
            if (gameLives < 0)
                isGameOver = true;
        }


    }
}

